package com.frame.ar.hander;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.jfinal.kit.StrKit;

/**
 * 作用描述：数据消息配置文件
 * 
 * @author LRC
 * @createDate 2015年10月20日
 * @version v1.0
 * @updateRecord 格式：时间，作者，修改说明
 ** 
 * 
 */
public class DataXMLHander {

	/**
	 * model配置文件名
	 */
	private String fileName = "data.cfg.xml";
	/**
	 * 单例对象
	 */
	private static DataXMLHander config = new DataXMLHander();

	public static DataXMLHander getInstance() {
		return config;
	}

	/**
	 * 消息映射
	 */
	private Map<String, Data> datas;

	public DataXMLHander() {
		try {
			datas = new HashMap<String, Data>();
			InputStream xml = DataXMLHander.class.getClassLoader()
					.getResourceAsStream(fileName);
			parse(xml);
		} catch (Exception e) {
			throw new RuntimeException("加载Model配置文件错误", e);
		}

	}

	/**
	 * 功能描述：再解析
	 * 
	 * @throws Exception
	 * @createDate 2015年10月21日 by LRC
	 * @updateRecord 格式：时间，作者，修改说明
	 ** 
	 * 
	 */
	public void parse() throws Exception {
		InputStream xml = DataXMLHander.class.getClassLoader()
				.getResourceAsStream(fileName);
		parse(xml);
	}

	/*******************************************
	 * 功能描述：解析配置文件
	 ******************************************* 
	 * @createDate 2015-9-11 by LRC
	 * @param xml
	 * @throws Exception
	 * @updateRecord 格式：时间，作者，修改说明
	 ******************************************* 
	 * 
	 */
	public void parse(InputStream xml) throws Exception {
		datas.clear();
		// 读取xml文件到document对象
		SAXReader reader = new SAXReader();
		Document doc = reader.read(xml);
		// 查找message
		List<Element> edatas = doc.selectNodes("/datas/data");
		Attribute id;
		Attribute name;
		for (Element edata : edatas) {
			id = edata.attribute("id");
			if (id != null) {
				Data data = new Data();
				data.id = id.getValue();// 设置消息id
				name = edata.attribute("name");
				data.name = name != null ? name.getValue() : "";// 设置消息名称

				// 解析数据集
				List<Element> eparams = edata.selectNodes("//data[@id='"
						+ data.id + "']/params/param");
				List<Param> params = new ArrayList<Param>();
				if (eparams.size() >= 0) {
					for (Element eparam : eparams) {
						// 获取类名
						id = eparam.attribute("id");
						if (id != null) {
							Param param = new Param();
							param.id = id.getValue();
							name = eparam.attribute("name");
							param.name = name != null ? name.getValue() : "";// 设置消息名称
							Attribute aRownum = eparam.attribute("rownum");
							param.rownum = aRownum != null ? Integer
									.parseInt(aRownum.getValue()) : 1;// 设置消息名称
							Attribute aFrom = eparam.attribute("from");
							param.from = aFrom != null ? aFrom.getValue()
									: "db";
							if ("db".equals(param.from)) {
								// 获取数据库查询sql
								param.sql = eparam.getText().trim();
								Attribute aDbSource = eparam
										.attribute("dbSource");
								if (aDbSource != null) {
									param.dbSource = StrKit.isBlank(aDbSource
											.getValue()) ? "main" : aDbSource
											.getValue();
								} else {
									param.dbSource = "main";
								}
							} else if ("list".equals(param.from)) {
								Map<String, Object> _data = new HashMap<String, Object>();
								// 获取数据列表
								List<Element> evalues = eparam
										.selectNodes("//data[@id='" + data.id
												+ "']/params/param[@id='"
												+ param.id + "']/value");
								Integer index = 1;
								for (Element evalue : evalues) {
									Attribute _aName = evalue.attribute("name");
									String _id = _aName != null ? _aName
											.getValue() : index + "";
									_data.put(_id, evalue.getText());
									index++;
								}
								param.data = _data;
							}
							params.add(param);
						}
					}
				}
				data.params = params;

				// 解析return
				List<Element> evalues = edata.selectNodes("//data[@id='"
						+ data.id + "']/return");
				Element evalue = evalues.get(0);
				Attribute aType = evalue.attribute("type");
				Return value = new Return();
				if (aType != null) {
					// 获取返回值类型
					value.type = Class.forName(aType.getValue());
					Attribute aFrom = evalue.attribute("from");
					value.from = aFrom != null ? aFrom.getValue() : "db";
					Attribute aAction = evalue.attribute("action");
					value.action = aAction != null ? aAction.getValue() : "find";
					Attribute aDbSource = evalue.attribute("dbSource");
					if (aDbSource != null) {
						value.dbSource = StrKit.isBlank(aDbSource.getValue()) ? "main"
								: aDbSource.getValue();
					} else {
						value.dbSource = "main";
					}
					// 解析条件
					// 解析when
					List<When> whens = new ArrayList<When>();
					List<Element> ewhens = evalue.selectNodes("//data[@id='"
							+ data.id + "']/return/when");
					if (ewhens.size() > 0) {
						for (Element ewhen : ewhens) {
							When when = new When();
							when.express = ewhen.elementTextTrim("express");
							when.sql = ewhen.elementTextTrim("sql");
							whens.add(when);
						}
					}
					value.whens = whens;
					
					//解析默认表达式
					value.othersSql = evalue.elementTextTrim("others");
					//解析columns
					String column = evalue.elementTextTrim("columns");
					if(!StrKit.isBlank(column)){
						//value.columns = column.split(",");
						value.columns = column;
					}
					//解析count
					String count = evalue.elementTextTrim("total");
					if(!StrKit.isBlank(count)){
						value.count = count;
					}
				}
				
				data.value = value;
				
				datas.put(data.id, data);
			}
		}
	}

	/**
	 * 消息
	 * 
	 * @param dataSource
	 * @param className
	 * @return
	 */
	public Data getData(String id) {
		Data data = this.datas.get(id);
		return data;
	}

	public class Data {
		public String id;
		public String name;
		public List<Param> params;
		public Return value;
	}

	public class Param {
		public String id;
		public String name;
		public Integer rownum = 1;
		public String sql;
		public String dbSource;
		public String from;// 数据获取方式 db list
		public Map<String, Object> data;
	}

	public class Return {
		public Class type;
		public String from;
		public String dbSource;
		public List<When> whens;
		public String othersSql;
		//public String[] columns;
		public String columns;
		public String count;
		public String action;//操作
	}

	public class When {
		public String express;
		public String sql;//from表达式
	}
	
	public static void main(String[] args) throws Exception {
		DataXMLHander h = new DataXMLHander();
		h.parse();
		System.out.println(h);
	}
}
